/**
 * 错误监控和日志系统
 * 专门处理微信小程序文本更新错误和其他DOM操作错误
 */

class ErrorMonitoringSystem {
  constructor() {
    this.errorLog = []
    this.errorStats = new Map()
    this.recoveryStrategies = new Map()
    this.maxLogSize = 1000
    this.isEnabled = true
    this._wxErrorHandlerSet = false
    
    // 初始化默认恢复策略
    this.initDefaultRecoveryStrategies()
    
    // 设置全局错误处理
    this.setupGlobalErrorHandling()
  }

  /**
   * 初始化默认恢复策略
   */
  initDefaultRecoveryStrategies() {
    // 32776 错误恢复策略
    this.setRecoveryStrategy('TEXT_UPDATE_32776', {
      maxRetries: 3,
      retryDelay: 100,
      backoffMultiplier: 2,
      fallbackAction: 'skip',
      handler: this.handle32776Error.bind(this)
    })

    // 组件销毁错误恢复策略
    this.setRecoveryStrategy('COMPONENT_DESTROYED', {
      maxRetries: 0,
      fallbackAction: 'cancel',
      handler: this.handleComponentDestroyedError.bind(this)
    })

    // 数据绑定时序错误恢复策略
    this.setRecoveryStrategy('TIMING_ERROR', {
      maxRetries: 2,
      retryDelay: 50,
      fallbackAction: 'defer',
      handler: this.handleTimingError.bind(this)
    })

    // 网络错误恢复策略
    this.setRecoveryStrategy('NETWORK_ERROR', {
      maxRetries: 3,
      retryDelay: 1000,
      backoffMultiplier: 1.5,
      fallbackAction: 'cache',
      handler: this.handleNetworkError.bind(this)
    })
  }

  /**
   * 设置全局错误处理
   */
  setupGlobalErrorHandling() {
    // 避免重复设置微信小程序错误处理
    if (typeof wx !== 'undefined' && wx.onError && !this._wxErrorHandlerSet) {
      this._wxErrorHandlerSet = true
      
      wx.onError((error) => {
        // 只处理真正的错误，忽略函数定义字符串
        if (typeof error === 'string' && (
          error.includes('function (error)') || 
          error.includes('function(error)') ||
          error.includes('_this.logError') ||
          error.includes('_this2.handleError')
        )) {
          return // 忽略函数定义被当作错误的情况
        }
        
        this.logError('GLOBAL_MP_ERROR', error, {
          source: 'miniprogram_global',
          timestamp: Date.now()
        })
      })
    }

    // Vue错误处理
    if (typeof window !== 'undefined') {
      window.addEventListener('error', (event) => {
        this.logError('GLOBAL_JS_ERROR', event.error, {
          source: 'javascript_global',
          filename: event.filename,
          lineno: event.lineno,
          colno: event.colno,
          timestamp: Date.now()
        })
      })

      window.addEventListener('unhandledrejection', (event) => {
        this.logError('UNHANDLED_PROMISE_REJECTION', event.reason, {
          source: 'promise_rejection',
          timestamp: Date.now()
        })
      })
    }
  }

  /**
   * 记录文本更新错误
   * @param {string} errorType - 错误类型
   * @param {Error|string} error - 错误对象或消息
   * @param {Object} context - 错误上下文
   */
  logTextUpdateError(errorType, error, context = {}) {
    if (!this.isEnabled) return

    const errorRecord = {
      id: this.generateErrorId(),
      type: errorType,
      message: typeof error === 'string' ? error : error.message,
      stack: error.stack || '',
      context: {
        ...context,
        timestamp: Date.now(),
        userAgent: this.getUserAgent(),
        platform: this.getPlatform()
      },
      retryCount: 0,
      resolved: false
    }

    // 特殊处理32776错误
    if (error.message && error.message.includes('32776')) {
      errorRecord.type = 'TEXT_UPDATE_32776'
      errorRecord.context.isTextViewError = true
    }

    this.addErrorRecord(errorRecord)
    this.updateErrorStats(errorType)
    
    // 尝试错误恢复
    this.attemptErrorRecovery(errorRecord)

    console.error(`[ErrorMonitoring] ${errorType}:`, errorRecord)
  }

  /**
   * 添加错误记录
   * @param {Object} errorRecord - 错误记录
   */
  addErrorRecord(errorRecord) {
    this.errorLog.push(errorRecord)
    
    // 限制日志大小
    if (this.errorLog.length > this.maxLogSize) {
      this.errorLog = this.errorLog.slice(-this.maxLogSize)
    }
  }

  /**
   * 更新错误统计
   * @param {string} errorType - 错误类型
   */
  updateErrorStats(errorType) {
    const stats = this.errorStats.get(errorType) || {
      count: 0,
      firstOccurrence: Date.now(),
      lastOccurrence: Date.now(),
      resolved: 0
    }

    stats.count++
    stats.lastOccurrence = Date.now()
    
    this.errorStats.set(errorType, stats)
  }

  /**
   * 设置恢复策略
   * @param {string} errorType - 错误类型
   * @param {Object} strategy - 恢复策略
   */
  setRecoveryStrategy(errorType, strategy) {
    this.recoveryStrategies.set(errorType, {
      maxRetries: 1,
      retryDelay: 100,
      backoffMultiplier: 1,
      fallbackAction: 'skip',
      ...strategy
    })
  }

  /**
   * 尝试错误恢复
   * @param {Object} errorRecord - 错误记录
   */
  async attemptErrorRecovery(errorRecord) {
    const strategy = this.recoveryStrategies.get(errorRecord.type)
    if (!strategy) {
      console.warn(`没有找到错误类型 ${errorRecord.type} 的恢复策略`)
      return
    }

    if (errorRecord.retryCount >= strategy.maxRetries) {
      console.warn(`错误 ${errorRecord.id} 已达到最大重试次数`)
      this.executeFallbackAction(errorRecord, strategy.fallbackAction)
      return
    }

    try {
      errorRecord.retryCount++
      
      // 计算延迟时间
      const delay = strategy.retryDelay * Math.pow(strategy.backoffMultiplier, errorRecord.retryCount - 1)
      
      console.log(`尝试恢复错误 ${errorRecord.id}，第 ${errorRecord.retryCount} 次重试，延迟 ${delay}ms`)
      
      // 延迟执行恢复
      setTimeout(async () => {
        try {
          const success = await strategy.handler(errorRecord)
          if (success) {
            errorRecord.resolved = true
            this.markErrorResolved(errorRecord.type)
            console.log(`错误 ${errorRecord.id} 恢复成功`)
          } else {
            // 继续重试
            this.attemptErrorRecovery(errorRecord)
          }
        } catch (recoveryError) {
          console.error(`错误恢复失败:`, recoveryError)
          this.attemptErrorRecovery(errorRecord)
        }
      }, delay)
      
    } catch (error) {
      console.error(`错误恢复过程中出现异常:`, error)
    }
  }

  /**
   * 执行降级操作
   * @param {Object} errorRecord - 错误记录
   * @param {string} action - 降级操作
   */
  executeFallbackAction(errorRecord, action) {
    console.log(`执行降级操作: ${action} for error ${errorRecord.id}`)
    
    switch (action) {
      case 'skip':
        // 跳过操作，不做任何处理
        break
      case 'cancel':
        // 取消相关操作
        this.cancelRelatedOperations(errorRecord)
        break
      case 'defer':
        // 延迟执行
        this.deferOperation(errorRecord)
        break
      case 'cache':
        // 使用缓存数据
        this.useCachedData(errorRecord)
        break
      default:
        console.warn(`未知的降级操作: ${action}`)
    }
  }

  /**
   * 处理32776错误
   * @param {Object} errorRecord - 错误记录
   * @returns {boolean} 是否恢复成功
   */
  async handle32776Error(errorRecord) {
    const { context } = errorRecord
    
    // 检查组件是否仍然存在
    if (context.component && context.componentId) {
      const isValid = this.validateComponent(context.component)
      if (!isValid) {
        console.log('组件已销毁，取消32776错误恢复')
        return true // 标记为已解决，因为组件不存在了
      }
    }

    // 尝试重新获取DOM元素
    if (context.elementId) {
      const element = this.findElement(context.elementId)
      if (!element) {
        console.log('DOM元素不存在，等待重新创建')
        return false // 继续重试
      }
    }

    // 尝试重新执行更新操作
    if (context.retryCallback && typeof context.retryCallback === 'function') {
      try {
        await context.retryCallback()
        return true
      } catch (error) {
        console.error('重试回调执行失败:', error)
        return false
      }
    }

    return false
  }

  /**
   * 处理组件销毁错误
   * @param {Object} errorRecord - 错误记录
   * @returns {boolean} 是否恢复成功
   */
  handleComponentDestroyedError(errorRecord) {
    // 组件已销毁，直接标记为已解决
    console.log('组件已销毁，取消相关操作')
    this.cancelRelatedOperations(errorRecord)
    return true
  }

  /**
   * 处理时序错误
   * @param {Object} errorRecord - 错误记录
   * @returns {boolean} 是否恢复成功
   */
  async handleTimingError(errorRecord) {
    const { context } = errorRecord
    
    // 等待DOM准备
    await this.waitForDOMReady()
    
    // 重新尝试操作
    if (context.retryCallback) {
      try {
        await context.retryCallback()
        return true
      } catch (error) {
        return false
      }
    }
    
    return false
  }

  /**
   * 处理网络错误
   * @param {Object} errorRecord - 错误记录
   * @returns {boolean} 是否恢复成功
   */
  async handleNetworkError(errorRecord) {
    // 检查网络连接
    const isOnline = await this.checkNetworkStatus()
    if (!isOnline) {
      console.log('网络未连接，稍后重试')
      return false
    }

    // 重新尝试网络请求
    if (errorRecord.context.retryCallback) {
      try {
        await errorRecord.context.retryCallback()
        return true
      } catch (error) {
        return false
      }
    }

    return false
  }

  /**
   * 标记错误已解决
   * @param {string} errorType - 错误类型
   */
  markErrorResolved(errorType) {
    const stats = this.errorStats.get(errorType)
    if (stats) {
      stats.resolved++
    }
  }

  /**
   * 获取错误统计
   * @returns {Object} 错误统计信息
   */
  getErrorStats() {
    const stats = {}
    this.errorStats.forEach((value, key) => {
      stats[key] = { ...value }
    })
    return stats
  }

  /**
   * 获取最近的错误日志
   * @param {number} limit - 限制数量
   * @returns {Array} 错误日志
   */
  getRecentErrors(limit = 50) {
    return this.errorLog.slice(-limit)
  }

  /**
   * 清理旧的错误日志
   * @param {number} maxAge - 最大保留时间（毫秒）
   */
  cleanupOldErrors(maxAge = 24 * 60 * 60 * 1000) { // 24小时
    const cutoff = Date.now() - maxAge
    this.errorLog = this.errorLog.filter(error => 
      error.context.timestamp > cutoff
    )
  }

  /**
   * 生成错误ID
   * @returns {string}
   */
  generateErrorId() {
    return `error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  }

  /**
   * 获取用户代理
   * @returns {string}
   */
  getUserAgent() {
    if (typeof navigator !== 'undefined') {
      return navigator.userAgent
    }
    if (typeof wx !== 'undefined' && wx.getSystemInfo) {
      return 'WeChat MiniProgram'
    }
    return 'Unknown'
  }

  /**
   * 获取平台信息
   * @returns {string}
   */
  getPlatform() {
    // #ifdef MP-WEIXIN
    return 'miniprogram'
    // #endif
    
    // #ifdef H5
    return 'h5'
    // #endif
    
    // #ifdef APP-PLUS
    return 'app'
    // #endif
    
    return 'unknown'
  }

  /**
   * 验证组件
   * @param {Object} component - 组件实例
   * @returns {boolean}
   */
  validateComponent(component) {
    if (!component) return false
    
    // Vue组件验证
    if (component.$data !== undefined) {
      return !component._isDestroyed && !component._isBeingDestroyed
    }
    
    // 微信小程序组件验证
    if (typeof component.setData === 'function') {
      return component.data !== undefined
    }
    
    return false
  }

  /**
   * 查找DOM元素
   * @param {string} elementId - 元素ID
   * @returns {Element|null}
   */
  findElement(elementId) {
    if (typeof document !== 'undefined') {
      return document.getElementById(elementId)
    }
    return null
  }

  /**
   * 等待DOM准备
   * @returns {Promise}
   */
  waitForDOMReady() {
    return new Promise(resolve => {
      if (typeof document !== 'undefined') {
        if (document.readyState === 'complete') {
          resolve()
        } else {
          document.addEventListener('DOMContentLoaded', resolve)
        }
      } else {
        // 微信小程序环境，简单延迟
        setTimeout(resolve, 50)
      }
    })
  }

  /**
   * 检查网络状态
   * @returns {Promise<boolean>}
   */
  checkNetworkStatus() {
    return new Promise(resolve => {
      if (typeof wx !== 'undefined' && wx.getNetworkType) {
        wx.getNetworkType({
          success: (res) => {
            resolve(res.networkType !== 'none')
          },
          fail: () => resolve(true) // 默认认为有网络
        })
      } else if (typeof navigator !== 'undefined') {
        resolve(navigator.onLine)
      } else {
        resolve(true)
      }
    })
  }

  /**
   * 取消相关操作
   * @param {Object} errorRecord - 错误记录
   */
  cancelRelatedOperations(errorRecord) {
    // 实现取消逻辑
    console.log(`取消与错误 ${errorRecord.id} 相关的操作`)
  }

  /**
   * 延迟操作
   * @param {Object} errorRecord - 错误记录
   */
  deferOperation(errorRecord) {
    // 实现延迟逻辑
    console.log(`延迟执行与错误 ${errorRecord.id} 相关的操作`)
  }

  /**
   * 使用缓存数据
   * @param {Object} errorRecord - 错误记录
   */
  useCachedData(errorRecord) {
    // 实现缓存逻辑
    console.log(`使用缓存数据处理错误 ${errorRecord.id}`)
  }

  /**
   * 启用/禁用错误监控
   * @param {boolean} enabled - 是否启用
   */
  setEnabled(enabled) {
    this.isEnabled = enabled
  }

  /**
   * 导出错误日志
   * @returns {string} JSON格式的错误日志
   */
  exportErrorLog() {
    return JSON.stringify({
      errors: this.errorLog,
      stats: this.getErrorStats(),
      exportTime: new Date().toISOString()
    }, null, 2)
  }
}

// 创建全局实例
const errorMonitoring = new ErrorMonitoringSystem()

// 定期清理旧错误
setInterval(() => {
  errorMonitoring.cleanupOldErrors()
}, 60 * 60 * 1000) // 每小时清理一次

export default errorMonitoring